package com.jinyi.wwdeng.autodialer.manager

import android.content.Context
import android.util.Log
import com.jinyi.wwdeng.autodialer.data.CallTask
import com.jinyi.wwdeng.autodialer.http.HttpApi
import com.jinyi.wwdeng.autodialer.http.HttpUtil
import com.jinyi.wwdeng.autodialer.repository.CallTaskRepository
import com.jinyi.wwdeng.autodialer.utils.AppConfig
import com.jinyi.wwdeng.autodialer.utils.AppException
import com.jinyi.wwdeng.autodialer.utils.ServiceConfig
import com.jinyi.wwdeng.autodialer.utils.event.EventAction
import com.jinyi.wwdeng.autodialer.utils.event.EventAction.ACTION_UPDATE_REPORT
import com.jinyi.wwdeng.autodialer.utils.event.EventAction.ACTION_UPDATE_TOAST
import com.jinyi.wwdeng.autodialer.utils.event.EventAction.EXTRA_MESSAGE
import com.jinyi.wwdeng.autodialer.utils.event.EventAction.EXTRA_PHONE_NUMBER
import com.jinyi.wwdeng.autodialer.utils.event.EventAction.EXTRA_STATUS
import kotlinx.coroutines.delay
import org.json.JSONObject
import java.util.concurrent.ConcurrentHashMap
import kotlin.time.Duration.Companion.seconds

/**
 * 数据上报管理器
 */
class ReportTaskManager(
    private val context: Context,
    private val taskRepository: CallTaskRepository,
    private val config: ServiceConfig
) {
    private final val TAG = "ReportTaskManager"
    private val processingTaskIds = ConcurrentHashMap<Long, Boolean>()

    suspend fun handleReportScheduling(): Boolean {
        return try {
            // 获取单个待上报任务
            val reportTasks = taskRepository.getReportPendingTasks(1)
            val reportTask = reportTasks.firstOrNull()
            if (reportTask == null){
                Log.d(TAG, "数据库没有上报数据，跳过")
                //更新上报状态
                EventAction.sendBroadcast(
                    ACTION_UPDATE_REPORT,
                    EXTRA_PHONE_NUMBER to "none",
                    EXTRA_STATUS to "空闲中",
                )
                false
            }
            reportTasks.firstOrNull()?.let { task ->
                if (!processingTaskIds.getOrDefault(task.id, false)) {
                    processingTaskIds[task.id] = true
                    try {
                        reportSingleDataWithRetry(task)
                        true
                    } finally {
                        processingTaskIds.remove(task.id)
                    }
                } else {
                    Log.d(TAG, "任务 ${task.id} 正在处理中，跳过")
                    false
                }
            } ?: false
        } catch (e: AppException.DatabaseException) {
            Log.e(TAG, "数据库操作失败", e)
            false
        } catch (e: Exception) {
            Log.e(TAG, "上报调度失败", e)
            false
        }
    }

    private suspend fun reportSingleDataWithRetry(task: CallTask) {
        Log.d(TAG, "开始上报任务 ${task.id}")

        var retryCount = task.reportRetryCount
        var success = false

        while (retryCount < config.maxRetryCount && !success) {
            try {
                val isSuccess = reportCallTaskData(task)
                if (isSuccess){
                    task.status = CallTask.CallStatus.COMPLETED
                    //更新上报状态
                    EventAction.sendBroadcast(
                        ACTION_UPDATE_REPORT,
                        EXTRA_PHONE_NUMBER to task.phoneNumber,
                        EXTRA_STATUS to CallTask.CallStatus.COMPLETED,
                    )
                    taskRepository.updateTaskStatus(task.id, CallTask.CallStatus.COMPLETED)
                }
                Log.d(TAG, "任务 ${task.id} 上报成功")
                success = isSuccess
            } catch (e: AppException.NetworkException) {
                retryCount++
                Log.w(TAG, "任务 ${task.id} 第${retryCount}次上报失败")
                taskRepository.incrementReportRetryCount(task.id)
                if (retryCount < config.maxRetryCount) {
                    delay(config.retryDelay.seconds)
                }
            }
        }

        if (!success) {
            Log.e(TAG, "任务 ${task.id} 上报最终失败")
            taskRepository.updateTaskStatusWithError(task.id, CallTask.CallStatus.UPLOAD_FAILED, "上报失败，重试${config.maxRetryCount}次后放弃")
        }
    }

    private suspend fun reportCallTaskData(task: CallTask): Boolean {
        try {
            val body = JSONObject().apply {
                put("sysLoginName",AppConfig.userName)
                put("token",AppConfig.userToken)
                put("mobile",task.phoneNumber)
                put("orderId",task.orderId ?: "")
                put("userId",task.userId ?: "")
                put("product",task.product ?: "")
                put("mobileType",task.mobileType ?: "")
                put("url",task.serverAudioPath ?: "")
                put("callRecord",task.callLog ?: "")
            }
            val data  = HttpUtil.getInstance().postJsonSuspend(context, HttpApi.API_SAVE_NUMBER_RECORD,body.toString(),null)
            val code = data.optInt("code")
            if (code != 0){
                //通知拨号管理器错误
                EventAction.sendBroadcast(
                    ACTION_UPDATE_TOAST,
                    EXTRA_STATUS to "error",
                    EXTRA_MESSAGE to "${data.optString("msg")}",
                )
                return false
            }
            //通知拨号管理器错误
            EventAction.sendBroadcast(
                ACTION_UPDATE_REPORT,
                EXTRA_STATUS to "success",
                EXTRA_PHONE_NUMBER to task.phoneNumber,
                EXTRA_MESSAGE to "${data.optString("msg")}",
            )
            return true
        } catch (e: Exception){
            throw AppException.FileUploadException("服务器响应错误")
        }
    }
}